﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Xml;

namespace SudokuPanel
{
    public partial class ScoreList : Form
    {
        public ScoreList()
        {
            InitializeComponent();
        }

        TabPage[] tps;
        ListView[] lvs;
        ConfigInfo ci = ConfigInfo.Instance();

        public String strSudokuReplay = "";
        public int nLvlInfo = 0;

        private void ScoreList_Load(object sender, EventArgs e)
        {
            SuspendLayout();
            ConfigInfo ci = ConfigInfo.Instance();
            int oldlvl = pubfun.str2int(ci["lvl", "1"]);
            if (oldlvl < 1 || oldlvl > ConfigInfo.lvlList.Length)
            {
                oldlvl = 1;
                ci["lvl"] = oldlvl.ToString();
            }

            lvs = new ListView[ConfigInfo.lvlList.Length];
            tps=new TabPage[ConfigInfo.lvlList.Length];

            for (int i = 0; i < ConfigInfo.lvlList.Length; ++i)
            {
                tps[i]= new TabPage();
                this.tabControl1.Controls.Add(tps[i]);
                tps[i].Text = ConfigInfo.lvlList[i];

                lvs[i] = new ListView();

                tps[i].Controls.Add(lvs[i]);

                //tps[i].Location = new System.Drawing.Point(4, 22);
                //tps[i].Size = new System.Drawing.Size(537, 267);
                tps[i].Name ="tabPage"+i;
                tps[i].Padding = new System.Windows.Forms.Padding(3);
                tps[i].TabIndex = i;
                tps[i].Text = ConfigInfo.lvlList[i];
                tps[i].UseVisualStyleBackColor = true;

                lvs[i].Dock = DockStyle.Fill;
                lvs[i].Location = new System.Drawing.Point(3, 30);
                //lvs[i].Size = new System.Drawing.Size(531, 261);
                lvs[i].Name = "listView"+i;
                lvs[i].TabIndex = 0;
                lvs[i].UseCompatibleStateImageBehavior = false;

                SudokuLibrary sl = new SudokuLibrary(ci["top_" + (i+1) + "_xml", "top" + (i+1) + ".xml"], 0);
                ListView lv = lvs[i];//注意顺序
                lv.BeginUpdate();
                lv.Sorting=SortOrder.Ascending;
                lv.CheckBoxes = true;
                lv.FullRowSelect = true;
                lv.MultiSelect = false;
                lv.Scrollable = true;
                lv.View = View.Details;
                lv.Columns.Add("题目",80);
                lv.Columns.Add("初始数", 60);
                lv.Columns.Add("用时",80);
                lv.Columns.Add("提示",60);
                lv.Columns.Add("撤销", 60);
                lv.Columns.Add("游戏日期",200);
                lv.ListViewItemSorter = new ListViewColumnSorter();
                lv.ColumnClick += new ColumnClickEventHandler(ListViewHelper.ListView_ColumnClick);
                lv.DoubleClick += new EventHandler(lv_DoubleClick);
                lv.Click += new EventHandler(lv_Click);
                foreach(XmlNode xn in sl)
                {
                    String strSudoku = xn.Name;
                    SudokuLibrary.removeSudokuPrefix(ref strSudoku);
                    XmlElement xe=(XmlElement) xn;
                    String strSeconds = xe.GetAttribute("seconds");
                    String strTips = xe.GetAttribute("tips");
                    String strUndoCount = xe.GetAttribute("undo_count");
                    String strUndoSteps = xe.GetAttribute("undo_steps");
                    String strUndo="";
                    if(pubfun.str2int(strUndoCount)>0)
                    {
                        strUndo+=strUndoCount+"次";
                        if(pubfun.str2int(strUndoCount)>0)
                        {
                            strUndo+=strUndoSteps+"步";
                        }
                    }
                    else
                        strUndo="0次";
                    String strDatetime = xe.GetAttribute("datetime");
                    ListViewItem lvi=lv.Items.Add(strSudoku, strSudoku,0);
                    lvi.SubItems.Add(pubfun.getClueNumber(strSudoku).ToString()+"数");
                    lvi.SubItems.Add(pubfun.getSecondsDesc(pubfun.str2int(strSeconds)).PadLeft(8));
                    lvi.SubItems.Add((strTips + "次").PadLeft(6));
                    lvi.SubItems.Add(strUndo.PadLeft(6));
                    DateTime dt = DateTime.Parse(strDatetime);
                    lvi.SubItems.Add(dt.ToString("yyyy年MM月dd日 HH时mm分ss秒"));
                }
                //设置根据游戏时间倒序
                ColumnClickEventArgs ev=new ColumnClickEventArgs(lv.Columns.Count-1);
                ListViewHelper.ListView_ColumnClick(lv, ev);
                ListViewHelper.ListView_ColumnClick(lv, ev);
                lv.EndUpdate();
            }
            tabControl1.SelectedIndexChanged += new EventHandler(tabControl1_SelectedIndexChanged);
            tabControl1.SelectedIndex = oldlvl-1;//设置当前难度
            ResumeLayout();
        }

        void lv_Click(object sender, EventArgs e)
        {
            foreach (ListViewItem lvi in lvs[tabControl1.SelectedIndex].SelectedItems)
            {
                lvi.Checked = !lvi.Checked;
                return;
            }
        }

        void lv_DoubleClick(object sender, EventArgs e)
        {
            btnReplay_Click(sender,e);
        }

        void checkButtonEnabled()
        {
            if(lvs[tabControl1.SelectedIndex].Items.Count == 0)
            {
                btnDeSelect.Enabled = false;
                btnRemove.Enabled = false;
                btnReplay.Enabled = false;
                btnCopy.Enabled = false;
            }
            else
            {
                btnDeSelect.Enabled = true;
                btnRemove.Enabled = true;
                btnReplay.Enabled = true;
                btnCopy.Enabled = true;
            }
        }

        void tabControl1_SelectedIndexChanged(object sender, EventArgs e)
        {
            //在这里处理操作按钮是否Enable
            checkButtonEnabled();
        }


        private void btnReplay_Click(object sender, EventArgs e)
        {
            int i = tabControl1.SelectedIndex;
            foreach(ListViewItem lvi in lvs[i].SelectedItems)
            {
                strSudokuReplay = lvi.Text;
                nLvlInfo = i + 1;
                Close();
                return;
            }
            MessageBox.Show("请先选择要重玩的题目！");
        }

        private void btnRemove_Click(object sender, EventArgs e)
        {
            int i = tabControl1.SelectedIndex;
            SudokuLibrary sl = new SudokuLibrary(ci["top_" + (i + 1) + "_xml", "top" + (i + 1) + ".xml"], 0);
            List<ListViewItem> items=new List<ListViewItem>();
            foreach (ListViewItem lvi in lvs[i].Items)
            {
                if (lvi.Checked)
                {
                    items.Add(lvi);
                }
            }
            if (items.Count==0)
                return;
            foreach(ListViewItem item in items)
            {
                sl.removeSudoku(item.Text);
                lvs[i].Items.Remove(item);
            }
            sl.Save();
            checkButtonEnabled();
        }

        private void btnCopy_Click(object sender, EventArgs e)
        {
            int i = tabControl1.SelectedIndex;
            String str = "";
            foreach (ListViewItem lvi in lvs[i].Items)
            {
                if(lvi.Checked)
                {
                    str += pubfun.formatPuzzleString(lvi.Text, pubfun.getFormatType(ConfigInfo.Instance()["PuzzleStringFormat"]));
                    str += "\r\n";
                }
            }
            if(str!="")
            {
                Clipboard.SetDataObject(str, true);
            }
            else
            {
                MessageBox.Show("你需要先选择要复制的题目！");
            }
        }

        private void btnSelectAll_Click(object sender, EventArgs e)
        {
            int i = tabControl1.SelectedIndex;
            foreach(ListViewItem lvi in lvs[i].Items)
            {
                lvi.Checked = true;
            }
        }

        private void btnAntiSelect_Click(object sender, EventArgs e)
        {
            int i = tabControl1.SelectedIndex;
            foreach (ListViewItem lvi in lvs[i].Items)
            {
                lvi.Checked = !lvi.Checked;
            }
        }

        private void btnDeSelect_Click(object sender, EventArgs e)
        {
            int i = tabControl1.SelectedIndex;
            foreach (ListViewItem lvi in lvs[i].Items)
            {
                lvi.Checked = false;
            }
        }

        private void buttonStartNew_Click(object sender, EventArgs e)
        {
            int i = tabControl1.SelectedIndex;
            strSudokuReplay = "New";
            nLvlInfo = i + 1;
            Close();
            return;

        }
    }

    /// <summary>
    /// 对ListView点击列标题自动排序功能
    /// </summary>
    public class ListViewHelper
    {
        /// <summary>
        /// 构造函数
        /// </summary>
        public ListViewHelper()
        {
            //
            // TODO: 在此处添加构造函数逻辑
            //
        }

        public static void ListView_ColumnClick(object sender, System.Windows.Forms.ColumnClickEventArgs e)
        {
            System.Windows.Forms.ListView lv = sender as System.Windows.Forms.ListView;

            int col = (lv.ListViewItemSorter as ListViewColumnSorter).SortColumn;
            lv.Columns[col].Text = lv.Columns[col].Text.Replace("↑", "");
            lv.Columns[col].Text = lv.Columns[col].Text.Replace("↓", "");

            // 检查点击的列是不是现在的排序列.

            if (e.Column == (lv.ListViewItemSorter as ListViewColumnSorter).SortColumn)
            {
                // 重新设置此列的排序方法.
                if ((lv.ListViewItemSorter as ListViewColumnSorter).Order == System.Windows.Forms.SortOrder.Ascending)
                {
                    (lv.ListViewItemSorter as ListViewColumnSorter).Order = System.Windows.Forms.SortOrder.Descending;
                    lv.Columns[e.Column].Text += "↓";
                }
                else
                {
                    (lv.ListViewItemSorter as ListViewColumnSorter).Order = System.Windows.Forms.SortOrder.Ascending;
                    lv.Columns[e.Column].Text += "↑";
               }
            }
            else
            {
                // 设置排序列，默认为正向排序
                (lv.ListViewItemSorter as ListViewColumnSorter).SortColumn = e.Column;
                (lv.ListViewItemSorter as ListViewColumnSorter).Order = System.Windows.Forms.SortOrder.Ascending;
                lv.Columns[e.Column].Text += "↑";
            }
            // 用新的排序方法对ListView排序
            ((System.Windows.Forms.ListView)sender).Sort();
        }
    }

    /// <summary>
    /// 继承自IComparer
    /// </summary>
    public class ListViewColumnSorter : System.Collections.IComparer
    {
        /// <summary>
        /// 指定按照哪个列排序
        /// </summary>
        private int ColumnToSort;
        /// <summary>
        /// 指定排序的方式
        /// </summary>
        private System.Windows.Forms.SortOrder OrderOfSort;
        /// <summary>
        /// 声明CaseInsensitiveComparer类对象
        /// </summary>
        private System.Collections.CaseInsensitiveComparer ObjectCompare;

        /// <summary>
        /// 构造函数
        /// </summary>
        public ListViewColumnSorter()
        {
            // 默认按第一列排序
            ColumnToSort = 0;

            // 排序方式为不排序
            OrderOfSort = System.Windows.Forms.SortOrder.None;

            // 初始化CaseInsensitiveComparer类对象
            ObjectCompare = new System.Collections.CaseInsensitiveComparer();
        }

        /// <summary>
        /// 重写IComparer接口.
        /// </summary>
        /// <param name="x">要比较的第一个对象</param>
        /// <param name="y">要比较的第二个对象</param>
        /// <returns>比较的结果.如果相等返回0，如果x大于y返回1，如果x小于y返回-1</returns>
        public int Compare(object x, object y)
        {
            int compareResult;
            System.Windows.Forms.ListViewItem listviewX, listviewY;

            // 将比较对象转换为ListViewItem对象
            listviewX = (System.Windows.Forms.ListViewItem)x;
            listviewY = (System.Windows.Forms.ListViewItem)y;

            string xText = listviewX.SubItems[ColumnToSort].Text;
            string yText = listviewY.SubItems[ColumnToSort].Text;

            int xInt, yInt;

            // 比较,如果值为IP地址，则根据IP地址的规则排序。
            if (IsIP(xText) && IsIP(yText))
            {
                compareResult = CompareIp(xText, yText);
            }
            else if (int.TryParse(xText, out xInt) && int.TryParse(yText, out yInt)) //是否全为数字
            {
                //比较数字
                compareResult = CompareInt(xInt, yInt);
            }
            else
            {
                //比较对象
                compareResult = ObjectCompare.Compare(xText, yText);
            }

            // 根据上面的比较结果返回正确的比较结果
            if (OrderOfSort == System.Windows.Forms.SortOrder.Ascending)
            {
                // 因为是正序排序，所以直接返回结果
                return compareResult;
            }
            else if (OrderOfSort == System.Windows.Forms.SortOrder.Descending)
            {
                // 如果是反序排序，所以要取负值再返回
                return (-compareResult);
            }
            else
            {
                // 如果相等返回0
                return 0;
            }
        }

        /// <summary>
        /// 判断是否为正确的IP地址，IP范围（0.0.0.0～255.255.255）
        /// </summary>
        /// <param name="ip">需验证的IP地址</param>
        /// <returns></returns>
        public bool IsIP(String ip)
        {
            return System.Text.RegularExpressions.Regex.Match(ip, @"^(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]{1}[0-9]{2}|[1-9]{1}[0-9]{1}|[0-9])$").Success;
        }

        /// <summary>
        /// 比较两个数字的大小
        /// </summary>
        /// <param name="ipx">要比较的第一个对象</param>
        /// <param name="ipy">要比较的第二个对象</param>
        /// <returns>比较的结果.如果相等返回0，如果x大于y返回1，如果x小于y返回-1</returns>
        private int CompareInt(int x, int y)
        {
            if (x > y)
            {
                return 1;
            }
            else if (x < y)
            {
                return -1;
            }
            else
            {
                return 0;
            }
        }

        /// <summary>
        /// 比较两个IP地址的大小
        /// </summary>
        /// <param name="ipx">要比较的第一个对象</param>
        /// <param name="ipy">要比较的第二个对象</param>
        /// <returns>比较的结果.如果相等返回0，如果x大于y返回1，如果x小于y返回-1</returns>
        private int CompareIp(string ipx, string ipy)
        {
            string[] ipxs = ipx.Split('.');
            string[] ipys = ipy.Split('.');

            for (int i = 0; i < 4; i++)
            {
                if (Convert.ToInt32(ipxs[i]) > Convert.ToInt32(ipys[i]))
                {
                    return 1;
                }
                else if (Convert.ToInt32(ipxs[i]) < Convert.ToInt32(ipys[i]))
                {
                    return -1;
                }
                else
                {
                    continue;
                }
            }
            return 0;
        }

        /// <summary>
        /// 获取或设置按照哪一列排序.
        /// </summary>
        public int SortColumn
        {
            set
            {
                ColumnToSort = value;
            }
            get
            {
                return ColumnToSort;
            }
        }

        /// <summary>
        /// 获取或设置排序方式.
        /// </summary>
        public System.Windows.Forms.SortOrder Order
        {
            set
            {
                OrderOfSort = value;
            }
            get
            {
                return OrderOfSort;
            }
        }
    }
}
